/*
 * Copyright (C) 2020 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.bobo.base.network;

import com.bobo.base.AppConstants;
import com.bobo.base.AppManager;
import com.bobo.base.R;
import com.bobo.base.network.base.BasicResponse;
import com.bobo.base.network.util.KLog;
import com.bobo.base.network.util.Result;
import com.bobo.base.utils.TokenUtils;
import com.bobo.base.utils.XToastUtils;
import com.google.gson.JsonParseException;

import org.json.JSONException;

import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.HttpException;

public abstract class NewDefaultObserver<T> implements Observer<T> {
    //  Activity 是否在执行onStop()时取消订阅
    private boolean isAddInStop = false;
    //    private MultiStateView multiStateView;
    private int pageIndex;
//    private MiniLoadingDialog mMiniLoadingDialog;
    private boolean needSendLogin=true;//是否需要发送登录通知

    public NewDefaultObserver() {
    }


    public NewDefaultObserver(boolean isShowLoading,boolean needSendLogin) {
        if (isShowLoading) {
            showProgress();
        }
        this.needSendLogin=needSendLogin;
    }


    public NewDefaultObserver(boolean isShowLoading) {
        if (isShowLoading) {
            showProgress();
        }
    }

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(T response) {
        dismissProgress();
        if (response instanceof BasicResponse) {
            BasicResponse r = (BasicResponse) response;
            if (r.getCode() == Result.OK) {
                onSuccess(response);
            } else {
                dismissProgress();
                String message = r.getMsg();
                switch (r.getCode()) {
                    case 402://token过期跳转到登录页面
                    case 401://token过期跳转到登录页面
                        if(TokenUtils.hasToken()){
                            TokenUtils.clearToken();
                        }
//                        EventBus.getDefault().post(new MessageEvent(MessageEvent.LOGIN_SUCCESSFUl, baseBean));
                        logiFail(message);
//                        if(needSendLogin){
//                            ActivityUtils.startActivity(LoginActivity.class);
//                        }
                        break;
                    default:
                        onCodeFail(message);
                        onCodeFail(message, r.getCode());
                        break;
                }
            }
        } else {
            onSuccess(response);
        }
    }

    private void showProgress() {
        try {
            if (AppManager.getInstance().currentActivity() != null) {
//                if (mMiniLoadingDialog == null) {
//                    mMiniLoadingDialog = WidgetUtils.getMiniLoadingDialog(AppManager.getInstance().currentActivity());
//                }
//                mMiniLoadingDialog.show();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void dismissProgress() {
//        if (mMiniLoadingDialog != null) {
//            try {
//                mMiniLoadingDialog.dismiss();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
    }

    @Override
    public void onError(Throwable e) {
        dismissProgress();

        KLog.e(e.getMessage());
        e.printStackTrace();
        onFail(e);
        if (e instanceof HttpException) {     //   HTTP错误
            onException(ExceptionReason.BAD_NETWORK);
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException) {   //   连接错误
            onException(ExceptionReason.CONNECT_ERROR);
        } else if (e instanceof InterruptedIOException) {   //  连接超时
            onException(ExceptionReason.CONNECT_TIMEOUT);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {   //  解析错误
            onException(ExceptionReason.PARSE_ERROR);
        } else {
            onException(ExceptionReason.UNKNOWN_ERROR);
        }
    }

    @Override
    public void onComplete() {
        dismissProgress();
    }

    /**
     * 请求成功
     *
     * @param response 服务器返回的数据
     */
    abstract public void onSuccess(T response);

    /**
     * 服务器返回数据，但响应码不为0
     * <p>
     * response 服务器返回的数据
     */
    public abstract void onFail(Throwable e);


    /**
     * 服务器code码错误回调
     *
     * @param message
     */
    protected void onCodeFail(String message) {
    }

    /**
     * 登录失败错误回调
     *
     * @param message
     */
    protected void logiFail(String message) {

    }

    protected void onCodeFail(String message, int code) {

    }


    /**
     * 请求异常
     *
     * @param reason
     */
    public void onException(ExceptionReason reason) {
        if (true) {
            return;
        }
        switch (reason) {
            case CONNECT_ERROR:
                XToastUtils.toast(R.string.connect_error);
                break;

            case CONNECT_TIMEOUT:
                XToastUtils.toast(R.string.connect_timeout);
                break;

            case BAD_NETWORK:
                if (AppConstants.isDebug)
                    XToastUtils.toast(R.string.bad_network);
                break;

            case PARSE_ERROR:
                if (AppConstants.isDebug)
                    XToastUtils.toast(R.string.parse_error);
                break;

            case UNKNOWN_ERROR:
            default:
                if (AppConstants.isDebug)
                    XToastUtils.toast(R.string.unknown_error);
                break;
        }
    }

    /**
     * 请求网络失败原因
     */
    public enum ExceptionReason {
        /**
         * 解析数据失败
         */
        PARSE_ERROR,
        /**
         * 网络问题
         */
        BAD_NETWORK,
        /**
         * 连接错误
         */
        CONNECT_ERROR,
        /**
         * 连接超时
         */
        CONNECT_TIMEOUT,
        /**
         * 未知错误
         */
        UNKNOWN_ERROR,
    }
}
